﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace IpSelector
{
    public class DnsHelper
    {
        public static readonly List<DnsItem> GoogleHost = new List<DnsItem>();
        public static AutoResetEvent waitHandle = new AutoResetEvent(false);

        static DnsHelper()
        {
            if (File.Exists("a.txt"))
            {
                string[] x = File.ReadAllText("a.txt").Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
                foreach (string s in x)
                {
                    GoogleHost.Add(new DnsItem(IPAddress.Parse(s), true));
                }
                return;
            }
            for (int i = 1; i < 256; i++)
            {
                GoogleHost.Add(new DnsItem(IPAddress.Parse("74.125.71." + i), true));
            }
        }

        public static void TestAccessbility()
        {
            Task.Factory.ContinueWhenAll(GoogleHost.FindAll((i) => i.UnAvailable == 0).Select(ip => Task.Factory.StartNew(TestAccessbilityAction, ip)).ToArray(), Sort);
        }

        private static void Sort(object state)
        {
            GoogleHost.Sort((a, b) => a.Delay.CompareTo(b.Delay));
            waitHandle.Set();
        }

        private static void TestAccessbilityAction(object parameter)
        {
            HttpWebResponse response = null;
            HttpWebRequest requestToProxy = null;
            DnsItem dnsItem = (DnsItem)parameter;
            try
            {

                string url = BuildUrl(dnsItem);
                requestToProxy = (HttpWebRequest)WebRequest.Create(url);
                requestToProxy.Host = "java2theworld.appspot.com";
                requestToProxy.Proxy = null;
                requestToProxy.Timeout = 5000;
                requestToProxy.AllowAutoRedirect = false;

                Stopwatch stopWatch = new Stopwatch();
                stopWatch.Start();

                response = (HttpWebResponse)requestToProxy.GetResponse();

                stopWatch.Stop();

                if (response.StatusCode == HttpStatusCode.OK)
                {
                    dnsItem.Available++;
                    dnsItem.Delay = stopWatch.ElapsedMilliseconds;
                    Console.WriteLine("{0} - OK, https = {1} {2}", dnsItem.Address, dnsItem.Https,dnsItem.Delay);
                }
                else
                {
                    dnsItem.UnAvailable++;
                    Console.WriteLine("{0} - unavailable, https={1}", dnsItem.Address, dnsItem.Https);
                }
            }
            catch (Exception e)
            {
                dnsItem.UnAvailable++;
                Console.WriteLine("{0} - unavailable, https={1}", dnsItem.Address, dnsItem.Https);
            }
            finally
            {
                if (response != null)
                {
                    response.Close();
                }
                if (requestToProxy != null)
                {
                    requestToProxy.Abort();
                }
            }
        }

        private static string BuildUrl(DnsItem dnsItem)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append(dnsItem.Https ? "https://" : "http://");
            sb.Append(dnsItem.Address.AddressFamily == AddressFamily.InterNetworkV6 ? "[" + dnsItem.Address + "]" : dnsItem.Address.ToString());
            sb.Append("/xpp2");
            return sb.ToString();
        }
    }
}
